package com.yanftch.hdc_tools.common

import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.openapi.application.ApplicationInfo
import com.intellij.openapi.extensions.PluginId
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.NlsSafe
import com.yanftch.hdc_tools.command.*
import com.yanftch.hdc_tools.insertcode.bean.CodeBean
import com.yanftch.hdc_tools.model.IdeInfo
import java.io.*
import java.nio.file.Files
import java.nio.file.Paths
import com.yanftch.hdc_tools.org.json.JSONObject;
import java.awt.Toolkit
import java.awt.datatransfer.Clipboard
import java.awt.datatransfer.StringSelection


/**
 * 是否有设备连接
 */
fun isDeviceConnected(hdcPath: String): Boolean {
    val executeCommand = executeCommand(finalCommandLine(hdcPath, hdc_list_targets))
    return !(executeCommand.isNullOrBlank() || "[Empty]" == executeCommand)
}


fun executeProcessBuilder(command: String): String {
    println("原始command：$command")
    val split = command.split(" ").toList()
    println("格式化的command：$split")
    val processBuilder = ProcessBuilder(split)
//    val processBuilder = ProcessBuilder("/Users/yanfeng/Documents/develop/harmonyOS/command-line-tools/sdk/HarmonyOS-NEXT-DB1/openharmony/toolchains/hdc", "uninstall", "com.yanftch.myapplication")
    processBuilder.redirectErrorStream(true)

    try {
        val process = processBuilder.start()
        val reader = BufferedReader(InputStreamReader(process.inputStream))
        val result = StringBuilder()
        var line: String?
        while ((reader.readLine().also { line = it }) != null) {
            result.append(line).append("\n")
        }
        val exitCode = process.waitFor()
        result.append("\n")
        result.append("Exited with code: $exitCode")

        reader.close()
        process.waitFor()

        return result.toString()
    } catch (e: Exception) {
        throw Exception()
        return "failed"
    }
}

fun executeCommand(command: String): String {
    val process = Runtime.getRuntime().exec(command)
    val reader = BufferedReader(InputStreamReader(process.inputStream))
    val result = StringBuilder()
    var line: String?

    while (reader.readLine().also { line = it } != null) {
        result.append(line).append("\n")
    }

    reader.close()
    process.waitFor()

    return result.toString()
}

fun writeStringToFile(fileName: String, content: String) {
    val file = File(fileName)
    file.writeText(content)
}

fun Any.readResourceFileContent(): String? {
    // 使用 ClassLoader 获取资源文件的输入流
    val inputStream = this::class.java.classLoader.getResourceAsStream("harmony_hdc_tools.hap")

    if (inputStream != null) {
        // 读取文件内容
        val content = StringBuilder()
        BufferedReader(InputStreamReader(inputStream)).use { reader ->
            var line: String?
            while (reader.readLine().also { line = it } != null) {
                content.append(line).append("\n")
            }
        }
        return content.toString()
    }

    return null
}

/**
 * 用于安装辅助APP
 */
fun Any.installAssistHap(hdcPath: String, fileName: String = "harmony_hdc_tools.hap"): Int {
    var exitCode = -1
    // 读取资源文件
    val inputStream: InputStream? = this::class.java.classLoader.getResourceAsStream(fileName)

    if (inputStream != null) {
        try {
            // 创建临时文件
            val tempFile = File.createTempFile("temp_entry", ".hap")
            tempFile.deleteOnExit()

            // 将资源文件写入临时文件
            FileOutputStream(tempFile).use { outputStream ->
                inputStream.copyTo(outputStream)
            }

            // 执行 adb install 命令安装 APK
            val command = hdcPath + " install -r ${tempFile.absolutePath}"
            val process = Runtime.getRuntime().exec(command)

            // 等待命令执行完成
            exitCode = process.waitFor()

            if (exitCode == 0) {
                println("hap 安装成功")
            } else {
                println("hap 安装失败，退出代码：$exitCode")
            }

            // 打印命令输出（可选）
//            process.inputStream.bufferedReader().forEachLine { println(it) }
//            process.errorStream.bufferedReader().forEachLine { println(it) }

        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            inputStream.close()
        }
    } else {
        println("无法找到资源文件 entry.hap")
    }
    return exitCode
}

fun waitUntil(timeoutMillis: Long = 30000L, step: Long = 100L, condition: () -> Boolean) {
    val endTime = System.currentTimeMillis() + timeoutMillis
    while (System.currentTimeMillis() < endTime) {
        if (condition()) {
            return
        }
        Thread.sleep(step)
    }
}


/**
 * 获取鸿蒙项目代码的 bundleName
 */
fun Project.getBundleName(): String {
    var bundleName: String? = ""
    try {
        val basePath: String = this.basePath ?: ""
        val configFilePath = Paths.get(basePath, "AppScope/app.json5")
        if (Files.exists(configFilePath)) {
            val configContent = String(Files.readAllBytes(configFilePath))
            val jsonObject = JSONObject(configContent)
            val obj2 = jsonObject["app"] as JSONObject?
            bundleName = obj2!!["bundleName"] as String?
            val versionName = obj2["versionName"] as String?
        }
    } catch (e: java.lang.Exception) {
        e.printStackTrace()
    }

    return bundleName ?: ""
}


/**
 * 判断 command 执行是否成功
 */
fun String?.isCommandSucceed(): Boolean {
    return !this.isNullOrEmpty() && this.contains("successfully")
}

fun finalCommandLine(vararg cmd: String): String {
    return cmd.joinToString(" ")
}

/**
 * 获取插件的版本号
 */
fun getPluginVersion(pluginId: String = "com.yanftch.hdc_tools"): String? {
    val plugin = PluginManagerCore.getPlugin(PluginId.getId(pluginId))
    return plugin?.version
}

fun getIDEInfo(): IdeInfo {
    var versionName = ""
    var version = ""
    var buildNumber = ""
    try {
        val appInfo = ApplicationInfo.getInstance()
        versionName = appInfo.versionName ?: ""
        version = appInfo.fullVersion ?: ""
        buildNumber = appInfo.build.asString() ?: ""
    } catch (e: Exception) {
    }

    return IdeInfo(versionName, version, buildNumber)
}

fun copyToClipboard(text: String) {
    // 获取系统剪贴板
    val clipboard: Clipboard = Toolkit.getDefaultToolkit().systemClipboard

    // 将文本包装成 StringSelection 对象
    val selection = StringSelection(text)

    // 将文本放入剪贴板
    clipboard.setContents(selection, null)
}


// 合并 两个 List
fun mergeLists(listA: List<CodeBean>?, listB: List<CodeBean>?): List<CodeBean> {
    if (listA.isNullOrEmpty()) return listB ?: emptyList()
    if (listB.isNullOrEmpty()) return listA

    // 将 ListB 转换成 Map 以便后续查找
    val mergedMap = listB.associateBy { it.name }.toMutableMap()

    // 遍历 ListA，进行合并
    for (codeA in listA) {
        // 如果 ListB 中存在相同的 name，优先保留 A 中的 value
        mergedMap[codeA.name] = codeA
    }

    // 将 Map 的 values 转回 List
    return mergedMap.values.toList()
}